-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch from ESTD to ETL #58
base: main
Are you sure you want to change the base?
Switch from ESTD to ETL #58
Conversation
thanks for your PR. It's impressive...it's massive! there is a lot of code that still needs formatting and it does not yet compile—those 2 things we need to solve first. |
Regarding code formatting: I did as "treefmt" suggested. |
Regarding compile: For me, it compiles and runs (on C++14). Update: I also fixed it for the CI builds C++17 and C++20. Or do you mean a different compile error I'm not aware of? I compiled:
|
b385542
to
80dff0c
Compare
BTW: I'm using my fork/branch of ETL at https://github.com/rolandreichweinbmw/etl/tree/openbsw-replace-estd - just for your reference. It includes some additions that I already contributed upstream, but no ETL release happened yet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm raising a few points where I see etl
being a step back from estl
to put them up for discussion.
Apart from those we should think about how to treat etl and it's development. Do we want to upstream changes? Maintain patches? Keep it as is? Maintain an "add-on" library for missing pieces (like the ones I commented on).
Also I'm wondering if we really gain a lot by adopting etl. Just because we can does not mean we should.
::util::logger::DOCAN); | ||
} | ||
|
||
void DoCanSystem::init() | ||
{ | ||
_classicAddressingFilter.init(::estd::make_slice(_addresses), ::estd::make_slice(_codecs)); | ||
_classicAddressingFilter.init( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there no comparable make_span
helpers in etl
that offer type deduction? I think it's quite beneficial to have/use those.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that they are really helpful.
There are deduction guides to the etl::span ctors:
https://github.com/ETLCPP/etl/blob/99d75375060b61aae49bb2fc06349b45cb2c3380/include/etl/span.h#L750
Unfortunately, only available w/ ETL_USING_CPP17
Maybe we can consider switching to C++17 in OpenBSW soon? :-)
For C++14, I can provide etl::make_span helper as we know from estd.
Update:
See: https://github.com/rolandreichweinbmw/etl/tree/span-make-span
And: ETLCPP/etl#1027
Now using it accordingly here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed not sure why it was not added to etl, because they have make_array for example. Could be a suggestion for ETL
@@ -52,7 +53,9 @@ class EcuIdList | |||
|
|||
uint16_t getSize() const | |||
{ | |||
return (fBufferLength == 0U) ? 0U : ::estd::read_be<uint16_t>(fpData); | |||
return (fBufferLength == 0U) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is quite a step back in readability. I wonder if this can be expressed more concisely with etl
.
One of the things we tried to achieve with estl was to eleminate the need to use reinterpret_cast
from most code as far as possible by providing safer alternatives. One reasoning for this is also that reinterpret_cast
often triggers warnings with safty related rulesets and using a safe wrapper api seems like a better approach over always adding suppression comments for those warnings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. I think the goal of ETL is also to achieve that "less usage of reinterpret_cast". Probably there is some other workaround for this specific use-case. Didn't try that out myself though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree!
That's why I contributed two alternative solutions to ETL some time ago:
-
unaligned_type_ext: https://github.com/rolandreichweinbmw/etl/tree/unaligned-type-ext
separate type; read/write e.g. via etl::be_uint16_t_ext{data} -
unaligned_type::at_address: https://github.com/rolandreichweinbmw/etl/tree/unaligned-type-at-address
pseudo constructor helper; e.g. etl::be_uint32_t::at_address(data)
I haven't used it yet in the above OpenBSW line since upstream has not decided yet which one to merge.
@@ -248,8 +258,9 @@ void TaskInitializer<Adapter>::create( | |||
TaskFunctionType const taskFunction, | |||
TaskConfigType const& config) | |||
{ | |||
::estd::slice<uint8_t> bytes = ::estd::make_slice(stack).template reinterpret_as<uint8_t>(); | |||
::estd::memory::align(alignof(StackType_t), bytes); | |||
::etl::span<uint8_t> bytes = ::etl::span<uint8_t>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another case of reinterpret_cast
being reintroduced in place of an api specifially designed to avoid it. (reinterpret_as
, which is safer as it also includes the length adjustment calculations)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed! But I wonder if this could be done in another way. Or if span could be construct in a different manner, because etl also offers reinterpret_as in etl/span.h. Haven't had the time to try that out myself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. I already contributed span::reinterpret_as() some time ago at:
https://github.com/rolandreichweinbmw/etl/tree/span-advance-copy-reinterpret-as
(Not yet available in upstream release, but we can already use it if you like as it is available in the ETL copy in this PR.)
{ | ||
(void)lastFrameIndex; | ||
if (!_sendPending) | ||
{ | ||
::estd::slice<uint8_t> payload = ::estd::slice<uint8_t>::from_pointer( | ||
::etl::span<uint8_t> payload( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We chose to use from_pointer
intead of overloading the constructor to make this less-safe and therefore less preferable way of creating slices/spans easier to spot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. Could be something to suggest also for ETL
::estd::slice<uint8_t> payload = payloadBuffer; | ||
EXPECT_TRUE(::estd::memory::is_equal(expectedPayload, payload)); | ||
::etl::span<uint8_t> payload = payloadBuffer; | ||
EXPECT_TRUE( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think here the estl
api was way better. It also has different behaviour, checking the equality of the sizes. However it does look like etl has etl::eqal
, why not use that here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed. We could have used etl::equal here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Adjusted accordingly.
frame.id = *reinterpret_cast<::etl::be_uint32_t*>(data.data()); | ||
data = data.subspan(sizeof(etl::be_uint32_t)); | ||
::etl::mem_copy(data.begin(), data.end(), frame.data.begin()); | ||
frame.data = frame.data.subspan(0, data.size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.trim()
as an inplace operation was introduced because some compilers used significantly more stack space when using .subslice()
. This may or may not be an issue with the compilers being used in the future, but it certainly was quite significant in the past.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no knowledge about this issue, but subspan seems more clear than trim. I know estd also has subslice, but they seem to be doing the same thing (both etl::span::subspan and estd::slice::subslice).
Also the fact that trim may reset the size of the slice to zero seems to be strange in my view (even though it is documented).
But really not sure about this point.
@@ -84,7 +85,7 @@ inline ::estd::slice<uint8_t> ForwardingReader::peek() const | |||
inline void ForwardingReader::release() | |||
{ | |||
// If _destinationData is an empty slice, copy will not copy any data. | |||
(void)::estd::memory::copy(_destinationData, _sourceData); | |||
(void)::etl::mem_copy(_sourceData.begin(), _sourceData.end(), _destinationData.begin()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
estd::memory::copy
is safer here as it also checks the destination length, which etl::mem_copy
obviously can't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we want safe copies, etl also offers that in copy_s in etl/algorithm.h
Also etl::mem_copy shouldn't check the length since it is a low level copy (basically memcpy but with pointers of the same time), so in this case it makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right.
When I previously contributed this addition to ETL:
ETLCPP/etl#1024
https://github.com/rolandreichweinbmw/etl/tree/span-advance-copy-reinterpret-as
... then I better also use it. :-)
Adjusting accordingly.
auto const v = ::estd::be_uint32_t::make(data); | ||
return appendData(v.bytes, 4) == 4; | ||
auto const v = ::etl::be_uint32_t(data); | ||
return appendData(static_cast<uint8_t const*>(v.data()), 4) == 4; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the estl
api is more clear here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the static_cast wasn't needed here. The method etl::unaligned_type_common::data() already returns a const uint8_t*.
Honestly since data is used on most containers to get a pointer to its raw buffer, I think data seems more aligned with the rest of the apis.
About the make method, seems to be a bit redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. I removed static_cast.
During the process for this PR, I already contributed some additions to ETL to easen its use in OpenBSW, and the author is quite responsive: https://github.com/ETLCPP/etl/issues?q=is%3Apr%20author%3Arolandreichweinbmw Most of it he already merged, but unfortunately, they are not yet in the master branch or released yet due to the ETL development process. However, I'm maintaining the changes relevant to OpenBSW in: https://github.com/rolandreichweinbmw/etl/tree/openbsw-replace-estd - see also the individual feature branches. I think for this purpose, we can maintain a fork or branches for changes not yet released in upstream ETL even though we should contribute all of it. One point for ETL is that some of the features I would like to contribute to OpenBSW are already based on ETL. And ETL is being used in projects where I would like to merge OpenBSW. Apart from ETL being established in the industry and public since many years. |
ac25775
to
812d4f8
Compare
b3394ff
to
a95b467
Compare
a95b467
to
cefb0c4
Compare
Just updated the branch and PR with new ETL upstream update, based on new ETL version 20.40.0, but with yet unmerged changes upstream that we need for easy switchover of OpenBSW to ETL. (As before, copied into the openbsw branch "use-etl".) New ETL branch with those additions for reference is: https://github.com/rolandreichweinbmw/etl/tree/openbsw-replace-estd |
As being discussed in #51 , this is a first request for review via pull request.